#ifndef CCEMATERIALPROGRAMEDITORDIALOG_H
#define CCEMATERIALPROGRAMEDITORDIALOG_H

#include <qdialog.h>
#include <material/materialeditor.h>
#include <ui_programeditorwidget.h>
#include <material/materialmanager.h>
#include <material/materialview.h>

class cceMaterialProgramTechniqueItem;
class cceMaterialShaderSlotItem;
class cceMaterialShaderItem;
class cceMaterialProgramPrimaryItem : public cceMaterialPrimaryItem
{
  Q_OBJECT
protected:
	void AddTechnique ();

public:
	cceMaterialProgramPrimaryItem ();

	void MoveTechnique (cceMaterialProgramTechniqueItem* technique, int direction);

	cceMaterialProgramTechniqueItem* AddTechniqueItem ();
	void RemoveTechnique (cceMaterialProgramTechniqueItem* technique);

	unsigned GetNumberOfTechniques () const;
	cceMaterialProgramTechniqueItem* GetTechnique (unsigned idx);

signals:
	void Changed ();
  void ShowEditor (cceMaterialItem* item);
};


class cceMaterialProgramTechniqueItem : public cceMaterialTechniqueItem 
{
  Q_OBJECT
private:
	cceMaterialProgramPrimaryItem	*_primary;

	QList<cceMaterialShaderItem*>		_shaders;
	cceMaterialShaderSlotItem			*_slot;

protected:
	virtual void RemoveTechnique ();
	virtual void MoveUp ();
	virtual void MoveDown ();

public:
	cceMaterialProgramTechniqueItem (cceMaterialProgramPrimaryItem* primary);

	unsigned GetNumberOfShaders ();
	cceMaterialShaderItem* GetShader (unsigned idx);

	cceMaterialShaderItem* AddShader (cceMaterialShader* shader);
	void RemoveShader (cceMaterialShaderItem* shaderItem);

signals:
	void Changed ();
	void ShowEditor (cceMaterialItem* item);
};

class cceMaterialShaderSlotItem : public cceMaterialSlotItem
{
private:
	cceMaterialProgramTechniqueItem* _technique;


protected:
	void dragEnterEvent (QGraphicsSceneDragDropEvent* evt);
	void dropEvent (QGraphicsSceneDragDropEvent* evt);

public:
	cceMaterialShaderSlotItem (cceMaterialProgramTechniqueItem* technique);

};

class cceMaterialShaderItem : public cceMaterialValueItem
{
  Q_OBJECT
private:
	cceMaterialProgramTechniqueItem* _technique;

	cceMaterialShader* _shader;

private slots:
  void onShaderChanged ();

protected:
	void dragEnterEvent (QGraphicsSceneDragDropEvent* evt);
	void dropEvent (QGraphicsSceneDragDropEvent* evt);

protected slots:
	void RemoveValue ();
  void ShaderClicked ();

public:
	cceMaterialShaderItem (cceMaterialProgramTechniqueItem* technique, cceMaterialShader* shader);

	cceMaterialShader* GetShader ();
	bool IsShader (cceMaterialShader* shader);

signals:
	void Changed ();
  void ShowEditor (cceMaterialItem* item);
};


class cceMaterialProgram;
class cceMaterialShaderTreeModel;
class cceMaterialProgramEditorDialog : public cceMaterialEditorAbstract
{
	Q_OBJECT
private:
	Ui::MaterialProgramEditorWidget	_gui;

	cceMaterialShaderTreeModel			*_shaderModel;
	cceMaterialView									*_programEditorView;

	cceMaterialProgram							*_program;
	cceMaterialProgramPrimaryItem		*_primaryItem;

private:
	bool UpdateProgramFromGUI ();
	void UpdateGUIFromProgram ();

	bool ProgramChanged ();

private slots:
  void ForceClose ();
	void Changed ();
	void on_lineEditName_textChanged (const QString& name);

public:
  cceMaterialProgramEditorDialog(QWidget* parent);

  QString GetName() const;
  virtual bool Save ();
	void SetProgram (cceMaterialProgram* program);

public slots:
	void Close ();
};

#endif // CCEMATERIALPROGRAMEDITORDIALOG_H
